package com.promise.jokerdream.manager

import android.content.Context
import com.promise.jokerdream.database.ExecutionLogDatabase
import com.promise.jokerdream.database.UserDataManager
import com.promise.jokerdream.model.log.ExecutionLog
import com.promise.jokerdream.response.pc.BasePCResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.util.UUID

/**
 * 执行记录管理器
 * 负责记录所有回包消息并持久化保存到数据库
 * 支持按用户分别存储和管理日志
 */
class ExecutionHistoryManager private constructor(private val context: Context) {
    
    private val database = ExecutionLogDatabase.getDatabase(context)
    private val logDao = database.executionLogDao()
    private val userDataManager = UserDataManager.getInstance(context)
    private val coroutineScope = CoroutineScope(Dispatchers.IO)
    
    // 内存中的日志列表，用于实时更新UI（当前用户的日志）
    private val _logs = MutableStateFlow<List<ExecutionLog>>(emptyList())
    val logs: StateFlow<List<ExecutionLog>> = _logs.asStateFlow()
    
    // 用于管理当前的 collect Job，避免多个 collect 同时运行
    private var currentCollectJob: Job? = null
    
    companion object {
        private const val MAX_LOG_AGE_DAYS = 30 // 最多保存30天的日志
        
        @Volatile
        private var instance: ExecutionHistoryManager? = null
        
        fun getInstance(context: Context): ExecutionHistoryManager {
            return instance ?: synchronized(this) {
                instance ?: ExecutionHistoryManager(context.applicationContext).also { instance = it }
            }
        }
    }
    
    init {
        // 启动定期清理任务
        startPeriodicCleanup()
        // 初始化时加载当前用户的日志
        loadCurrentUserLogs()
    }
    
    /**
     * 获取当前用户ID
     */
    private fun getCurrentUserId(): String {
        return userDataManager.getCurrentAccount()?.userId ?: ""
    }
    
    /**
     * 刷新当前用户的日志
     */
    fun refreshCurrentUserLogs() {
        loadCurrentUserLogs()
    }
    
    /**
     * 记录自定义消息
     */
    fun addHistory(operation: String, message: String?, result: Int = 0, extra: String = "") {
        val currentUserId = getCurrentUserId()
        if (currentUserId.isEmpty()) {
            // 如果没有当前用户，不记录日志
            return
        }
        
        val log = ExecutionLog(
            id = UUID.randomUUID().toString(),
            userId = currentUserId,
            timestamp = System.currentTimeMillis(),
            operation = operation,
            message = message ?: "",
            result = result,
            extra = extra
        )
        addLog(log)
    }
    
    /**
     * 添加日志到数据库和内存
     */
    private fun addLog(log: ExecutionLog) {
        // 异步保存到数据库
        coroutineScope.launch {
            logDao.insertLog(log)
        }
        
        // 同步更新内存中的日志列表
        val currentLogs = _logs.value.toMutableList()
        currentLogs.add(0, log)
        _logs.value = currentLogs
    }
    
    /**
     * 获取所有日志（从数据库）
     */
    fun getAllLogs(): Flow<List<ExecutionLog>> {
        return logDao.getAllLogs()
    }
    
    /**
     * 获取当前用户的所有日志
     */
    fun getCurrentUserLogs(): Flow<List<ExecutionLog>> {
        val currentUserId = getCurrentUserId()
        return if (currentUserId.isNotEmpty()) {
            logDao.getLogsByUser(currentUserId)
        } else {
            kotlinx.coroutines.flow.flowOf(emptyList())
        }
    }
    
    /**
     * 分页获取日志
     */
    suspend fun getLogsPaged(page: Int, pageSize: Int): List<ExecutionLog> {
        return logDao.getLogsPaged(pageSize, page * pageSize)
    }
    
    /**
     * 分页获取当前用户的日志
     */
    suspend fun getCurrentUserLogsPaged(page: Int, pageSize: Int): List<ExecutionLog> {
        val currentUserId = getCurrentUserId()
        return if (currentUserId.isNotEmpty()) {
            logDao.getUserLogsPaged(currentUserId, pageSize, page * pageSize)
        } else {
            emptyList()
        }
    }
    
    /**
     * 按操作类型筛选日志
     */
    fun getLogsByOperation(operation: String): Flow<List<ExecutionLog>> {
        return logDao.getLogsByOperation(operation)
    }
    
    /**
     * 按操作类型筛选当前用户的日志
     */
    fun getCurrentUserLogsByOperation(operation: String): Flow<List<ExecutionLog>> {
        val currentUserId = getCurrentUserId()
        return if (currentUserId.isNotEmpty()) {
            logDao.getUserLogsByOperation(currentUserId, operation)
        } else {
            kotlinx.coroutines.flow.flowOf(emptyList())
        }
    }
    
    /**
     * 按结果状态筛选日志
     */
    fun getLogsByResult(result: Int): Flow<List<ExecutionLog>> {
        return logDao.getLogsByResult(result)
    }
    
    /**
     * 按结果状态筛选当前用户的日志
     */
    fun getCurrentUserLogsByResult(result: Int): Flow<List<ExecutionLog>> {
        val currentUserId = getCurrentUserId()
        return if (currentUserId.isNotEmpty()) {
            logDao.getUserLogsByResult(currentUserId, result)
        } else {
            kotlinx.coroutines.flow.flowOf(emptyList())
        }
    }
    
    /**
     * 获取最近N条日志
     */
    suspend fun getRecentLogs(count: Int): List<ExecutionLog> {
        return logDao.getRecentLogs(count)
    }
    
    /**
     * 按时间范围获取日志
     */
    fun getLogsByTimeRange(startTime: Long, endTime: Long): Flow<List<ExecutionLog>> {
        return logDao.getLogsByTimeRange(startTime, endTime)
    }
    
    
    /**
     * 清空所有日志
     */
    fun clearAllLogs() {
        coroutineScope.launch {
            logDao.clearAllLogs()
        }
        _logs.value = emptyList()
    }
    
    /**
     * 清空当前用户的所有日志
     */
    fun clearCurrentUserLogs() {
        val currentUserId = getCurrentUserId()
        if (currentUserId.isNotEmpty()) {
            coroutineScope.launch {
                logDao.clearUserLogs(currentUserId)
            }
            _logs.value = emptyList()
        }
    }
    
    /**
     * 删除指定日志
     */
    fun deleteLog(logId: String) {
        coroutineScope.launch {
            logDao.deleteLog(logId)
        }
        val currentLogs = _logs.value.toMutableList()
        currentLogs.removeAll { it.id == logId }
        _logs.value = currentLogs
    }
    
    /**
     * 加载当前用户的日志到内存
     */
    private fun loadCurrentUserLogs() {
        // 取消之前的 collect，避免多个 collect 同时运行
        currentCollectJob?.cancel()
        
        currentCollectJob = coroutineScope.launch {
            try {
                val currentUserId = getCurrentUserId()
                if (currentUserId.isNotEmpty()) {
                    val userLogs = logDao.getLogsByUser(currentUserId)
                    userLogs.collect { logs ->
                        _logs.value = logs
                    }
                } else {
                    _logs.value = emptyList()
                }
            } catch (e: Exception) {
                e.printStackTrace()
                _logs.value = emptyList()
            }
        }
    }
    
    /**
     * 启动定期清理任务
     */
    private fun startPeriodicCleanup() {
        coroutineScope.launch {
            while (true) {
                kotlinx.coroutines.delay(24 * 60 * 60 * 1000L) // 24小时
                cleanupOldLogs()
            }
        }
    }
    
    /**
     * 清理过期日志
     */
    private suspend fun cleanupOldLogs() {
        try {
            val cutoffTime = System.currentTimeMillis() - (MAX_LOG_AGE_DAYS * 24 * 60 * 60 * 1000L)
            logDao.deleteLogsBefore(cutoffTime)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}
